#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#       nucleo.py
#       
#       Copyright 2011 Cleve <mauricio.cleveland@gmail.com>
#       
#       This program is free software; you can redistribute it and/or modify
#       it under the terms of the GNU General Public License as published by
#       the Free Software Foundation; either version 2 of the License, or
#       (at your option) any later version.
#       
#       This program is distributed in the hope that it will be useful,
#       but WITHOUT ANY WARRANTY; without even the implied warranty of
#       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#       GNU General Public License for more details.
#       
#       You should have received a copy of the GNU General Public License
#       along with this program; if not, write to the Free Software
#       Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
#       MA 02110-1301, USA.
#       
#       

class Nucleo:
  """ Definicion de los nucleos que se fusionan """  
  def __init__ (self, identificador, coordenadas_actuales, m_distancia_original, enlace1, enlace2):
    """ Class initialiser """
    self.identificador = identificador
    self.coordenadas = coordenadas_actuales
    
    self.masa = len(list(enlace1)+list(enlace2))
    
    #Matriz de distancia para encontrar mejores distancias de enlaces.
    self.m_distancia = m_distancia_original
    
    #Creo lista para almacenar enlaces.
    self.enlaces = []
      
    #Metodo minimizador de rutas.
    self.MinimaRuta(list(enlace1), list(enlace2))
    
    #print 'Nucleo ',self.identificador,' - interior: ',list(enlace1)+list(enlace2)
      
  def CalculaDistancia(self, enlace):
    """ Function doc
  
    @param PARAM: DESCRIPTION
    @return RETURN: DESCRIPTION
    """
    
    suma=0
      
    #Recorrer enlaces y realizar suma.
    for i in xrange(len(enlace)):
      if i < len(enlace)-1:
        suma = self.m_distancia[enlace[i]][enlace[i+1]] + suma
        
    return (suma,enlace)

  
  def MinimaRuta(self, enlace1, enlace2):
    """ Minimiza la distancia evitando cruzamiento.
  
    @return None: Ruta minima entre los enlaces del nucleo.
    """
    enlace1 = list(enlace1)
    enlace2 = list(enlace2)
    
    rutas_parciales = []
    if len(enlace2) != 0:
      #Combinar enlaces para obtener mejor ruta.
      rutas_parciales.append(self.CalculaDistancia(enlace1+enlace2))
      enlace2.reverse()
      rutas_parciales.append(self.CalculaDistancia(enlace1+enlace2))
      enlace1.reverse()
      rutas_parciales.append(self.CalculaDistancia(enlace1+enlace2))
      rutas_parciales.append(self.CalculaDistancia(enlace1+enlace2))
          
      #Selecciono mejor ruta segun distancia.
      rutas_parciales = sorted(rutas_parciales)[0][1]
      
      self.enlaces = rutas_parciales
      
    else:
      self.enlaces = enlace1

